package com.music.glide.util.pool

import android.util.Log
import androidx.core.util.Pools
import kotlin.collections.List

/**
 * 提供了一些用于创建和管理对象池（pool）的工具
 * 尤其是在需要重复使用对象时
 * 对象池的目的是通过减少对象的创建和销毁次数来提高性能
 */

class KFactoryPools private constructor() {
    interface Factory<T> {
        fun create(): T
    }

    interface ReSetter<T> {
        fun reset(obj: T)
    }

    interface PoolAble {
        fun getVerifier(): KStateVerifier
    }

    class FactoryPool<T : Any>(
        private var pool: Pools.Pool<T>,
        private var factory: Factory<T>,
        private var resetter: ReSetter<T>
    ) : Pools.Pool<T> {
        override fun acquire(): T {
            var result = pool.acquire()
            if (result == null) {
                result = factory.create()
            }
            Log.d(TAG, "Create new ${result::javaClass}")
            if (result is PoolAble) {
                result.getVerifier().setRecycled(false)
            }
            return result
        }

        override fun release(instance: T): Boolean {
            if (instance is PoolAble) {
                instance.getVerifier().setRecycled(true)
            }
            resetter.reset(instance)
            return pool.release(instance)
        }
    }

    companion object {

        const val TAG = "KFactoryPools"

        const val DEFAULT_POOL_SIZE = 20

        private val EmptyReSetter = object : ReSetter<Any> {
            override fun reset(obj: Any) {

            }
        }

        fun <T : PoolAble> simple(size:Int, factory: Factory<T>):Pools.Pool<T> {
            return build(Pools.SimplePool(size), factory)
        }

        fun <T : PoolAble> threadSate(size:Int, factory: Factory<T>):Pools.Pool<T> {
            return build(Pools.SynchronizedPool(size), factory)
        }

        fun <T> threadSafeList(size: Int = DEFAULT_POOL_SIZE): Pools.Pool<MutableList<T>> {
            return build(Pools.SynchronizedPool(size), object : Factory<MutableList<T>> {
                override fun create(): MutableList<T> {
                    return mutableListOf()
                }
            }, object : ReSetter<MutableList<T>> {
                override fun reset(obj: MutableList<T>) {
                    obj.clear()
                }
            })
        }

        fun <T : Any> build(
            pool: Pools.Pool<T>, factory: Factory<T>, reSetter: ReSetter<T>? = null
        ): Pools.Pool<T> {
            return FactoryPool(pool, factory, reSetter?: emptyReSetter())
        }
        @Suppress("UNCHECKED_CAST")
        private fun <T : Any> emptyReSetter(): ReSetter<T> {
            return EmptyReSetter as ReSetter<T>
        }
    }
}